package com.abel.bigwater.kmgw

import com.abel.bigmeter.service.DataParam
import com.abel.bigwater.data.BcdString
import com.abel.bigwater.dataserver.model.ServiceConfig
import com.abel.bigwater.kmgw.dao.RtuDao
import com.abel.bigwater.mapper.DataMapper
import com.abel.bigwater.mapper.MeterMapper
import com.abel.bigwater.mapper.RtuMapper
import com.abel.bigwater.model.zone.ZoneMeter
import com.alibaba.fastjson.JSON
import io.netty.buffer.Unpooled
import io.netty.channel.embedded.EmbeddedChannel
import io.netty.channel.socket.DatagramPacket
import org.joda.time.DateTime
import org.junit.Assert.assertTrue
import org.junit.Test
import org.junit.runner.RunWith
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.context.annotation.ComponentScan
import org.springframework.test.context.junit4.SpringRunner
import java.net.InetSocketAddress

@SpringBootTest(classes = [EwideServerHandlerTest::class])
@RunWith(SpringRunner::class)
@ComponentScan(basePackages = ["com.abel.bigwater"])
class EwideServerHandlerTest {

    @Autowired
    var rtuDao: RtuDao? = null

    @Autowired
    var dataMapper: DataMapper? = null

    @Autowired
    var meterMapper: MeterMapper? = null

    @Autowired
    var rtuMapper: RtuMapper? = null

    @Test
    fun channelRead() {
    }

    @Test
    fun `handleTermReq`() {
        val config = ServiceConfig().apply {
            this.firmId = "11"
        }
        val handler = EwideServerHandler(dataMapper, meterMapper, rtuMapper, rtuDao, config)

        val h = EmbeddedChannel(EwideDecoder(), handler)

        h.writeInbound(Unpooled.buffer().writeBytes(BcdString.toByteArray(DEMO_REQ)))

        Thread.sleep(2000)
    }

    @Test
    fun `handleData`() {
        val config = ServiceConfig().apply {
            this.firmId = "11"
        }
        val handler = EwideServerHandler(dataMapper, meterMapper, rtuMapper, rtuDao, config)

        val h = EmbeddedChannel(EwideDecoder(), handler)

        h.writeInbound(Unpooled.buffer().writeBytes(BcdString.toByteArray(DEMO_DATA)))

        Thread.sleep(2000)
    }

    @Test
    fun `handleDataPulse`() {
        val m1 = ZoneMeter().apply {
            id = "qy-0300000001-83"
            name = "测试0300000001"
            firmId = "11"

            extId = "0300000001-83"
            meterPulse = 10.0
        }
        meterMapper!!.insertMeter(m1)

        try {
            val config = ServiceConfig().apply {
                this.firmId = "11"
            }
            val handler = EwideServerHandler(dataMapper, meterMapper, rtuMapper, rtuDao, config)

            val h = EmbeddedChannel(EwideDecoder(), handler)

            h.writeInbound(Unpooled.buffer().writeBytes(BcdString.toByteArray(DEMO_DATA)))

            Thread.sleep(2000)

            val dlist = dataMapper!!.selectRealtime(DataParam(extId = m1.extId).apply {
                sampleTime1 = DateTime(2019, 7, 1, 2, 3, 4).minusMillis(1).toDate()
            })
            lgr.info(JSON.toJSONString(dlist))
            assertTrue(dlist.first().literPulse.toInt() == 10)
        } finally {
            meterMapper!!.deleteMeter(listOf(m1.id!!))
        }
    }

    @Test
    fun `handleShutdown`() {
        val config = ServiceConfig().apply {
            this.firmId = "11"
        }
        val handler = EwideServerHandler(dataMapper, meterMapper, rtuMapper, rtuDao, config)

        val h = EmbeddedChannel(EwideDecoder(), handler)

        h.writeInbound(Unpooled.buffer().writeBytes(BcdString.toByteArray(DEMO_SHUT)))

        Thread.sleep(2000)
    }

    @Test
    fun `handleBurst`() {
        val config = ServiceConfig().apply {
            this.firmId = "11"
        }
        val handler = EwideServerHandler(dataMapper, meterMapper, rtuMapper, rtuDao, config)

        val h = EmbeddedChannel(EwideDecoder(), handler)

        h.writeInbound(Unpooled.buffer().writeBytes(BcdString.toByteArray(DEMO_BURST)))

        Thread.sleep(2000)
    }

    @Test
    fun handleUdpShutdown() {
        val config = ServiceConfig().apply {
            this.firmId = "11"
        }
        val handler = EwideServerHandler(dataMapper, meterMapper, rtuMapper, rtuDao, config)

        val h = EmbeddedChannel(EwideDecoder(), handler)

        val buf = Unpooled.buffer().writeBytes(BcdString.toByteArray(DEMO_REQ))
        val gram = DatagramPacket(buf, InetSocketAddress(DEMO_PORT))
        h.writeInbound(gram)

        Thread.sleep(2000)
    }

    companion object {
        const val DEMO_REQ = "5A55010000000301020101000700700A0085898D872EEC6A69"
        const val DEMO_DATA = "5A55010000000301020101001D00710200010001032019070102030483D204000087D5DD00008D15BF34000D576A69"
        const val DEMO_SHUT = "5A55010000000301020101000100F09A036A69"
        const val DEMO_BURST = "5A55010000000301020101000B008220130721200129000000119C6A69"

        const val DEMO_PORT = 6337

        private val lgr = LoggerFactory.getLogger(EwideServerHandlerTest::class.java)
    }
}